﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SimpleCompiler
{
    enum BinaryOperator
    {
        unknown, 
        equal_to, // == 
        not_equal_to, // !=
        less_than, // <
        less_equal_than, // <=
        great_than, // >
        great_equal_than, // >=

        assign, // =


        add,
        sub,
        mul,
        div,        
    }
    // + - * /  = ==
    internal class ExpressionBinary : Expression 
    {
        public BinaryOperator binaryOperator;
        public Statement left;
        public Statement right;

        public ExpressionBinary(BinaryOperator binaryOperator, Statement left, Statement right)
        {
            this.binaryOperator = binaryOperator;
            this.left = left;
            this.right = right;
        }

        public override Variable Execute(RuntimeVariableScope scope)
        {
            if (binaryOperator == BinaryOperator.add)
            {
                return new Variable() { value =  left.Execute(scope).value.add(right.Execute(scope).value) };
            }
            else if (binaryOperator == BinaryOperator.sub)
            {
                return new Variable() { value = left.Execute(scope).value.sub(right.Execute(scope).value) };
            }
            else if (binaryOperator == BinaryOperator.mul)
            {
                return new Variable() { value = left.Execute(scope).value.mul(right.Execute(scope).value) };
            }
            else if (binaryOperator == BinaryOperator.div)
            {
                return new Variable() { value = left.Execute(scope).value.div(right.Execute(scope).value) };
            }

            else if (binaryOperator == BinaryOperator.assign)
            {
                left.Execute(scope).value.assign_from(right.Execute(scope).value);
                return Variable.None;
            }
            else if (binaryOperator == BinaryOperator.equal_to)
            {
                return new Variable() { value = new TypeBool() { value = left.Execute(scope).value.equals_to(right.Execute(scope).value)} };
            }
            else if (binaryOperator == BinaryOperator.not_equal_to)
            {
                return new Variable() { value = new TypeBool() { value = left.Execute(scope).value.not_equals_to(right.Execute(scope).value) } };
            }
            else if (binaryOperator == BinaryOperator.less_than)
            {
                return new Variable() { value = new TypeBool() { value = left.Execute(scope).value.less_than(right.Execute(scope).value) } };
            }
            else if (binaryOperator == BinaryOperator.less_equal_than)
            {
                return new Variable() { value = new TypeBool() { value = left.Execute(scope).value.less_equal_than(right.Execute(scope).value) } };
            }
            else if (binaryOperator == BinaryOperator.great_than)
            {
                return new Variable() { value = new TypeBool() { value = left.Execute(scope).value.great_than(right.Execute(scope).value) } };
            }
            else if (binaryOperator == BinaryOperator.great_equal_than)
            {
                return new Variable() { value = new TypeBool() { value = left.Execute(scope).value.great_equal_than(right.Execute(scope).value) } };
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
    }



}
